# -*- coding: utf-8 -*-
"""
心理咨询师服务系统 - 测评模型
"""

from datetime import datetime
from sqlalchemy import Column, Integer, String, Text, Boolean, DateTime, ForeignKey, Enum, Float, JSON
from sqlalchemy.orm import relationship
from .base import BaseModel
import enum


class AssessmentStatus(enum.Enum):
    """测评状态"""
    IN_PROGRESS = 'in_progress'  # 进行中
    COMPLETED = 'completed'  # 已完成
    ABANDONED = 'abandoned'  # 已放弃
    EXPIRED = 'expired'  # 已过期


class Assessment(BaseModel):
    """测评记录"""
    __tablename__ = 'assessments'
    
    # 基本信息
    user_id = Column(Integer, ForeignKey('users.id'), nullable=True, comment='用户ID（匿名用户可为空）')
    scale_id = Column(Integer, ForeignKey('scales.id'), nullable=False, comment='量表ID')
    publication_id = Column(Integer, ForeignKey('member_scale_publications.id'), nullable=True, comment='发布记录ID')
    
    # 测评状态
    status = Column(Enum(AssessmentStatus), default=AssessmentStatus.IN_PROGRESS, comment='测评状态')
    
    # 时间信息
    started_at = Column(DateTime, default=datetime.utcnow, comment='开始时间')
    completed_at = Column(DateTime, comment='完成时间')
    expired_at = Column(DateTime, comment='过期时间')
    
    # 进度信息
    current_question = Column(Integer, default=1, comment='当前题目序号')
    total_questions = Column(Integer, comment='总题目数')
    progress_percentage = Column(Float, default=0.0, comment='完成百分比')
    
    # 时间统计
    time_spent = Column(Integer, default=0, comment='已用时间(秒)')
    estimated_time = Column(Integer, comment='预估时间(秒)')
    
    # 设备和环境信息
    device_info = Column(JSON, comment='设备信息')
    ip_address = Column(String(45), comment='IP地址')
    user_agent = Column(Text, comment='用户代理')
    
    # 测评配置
    is_anonymous = Column(Boolean, default=False, comment='是否匿名测评')
    allow_review = Column(Boolean, default=True, comment='是否允许回顾答案')
    time_limit = Column(Integer, comment='时间限制(秒)')
    
    # 来源信息 - 暂时注释，数据库中不存在这些字段
    # source_type = Column(String(50), comment='来源类型(member, public, admin等)')
    # source_id = Column(String(100), comment='来源ID')
    
    # 计分信息 - 暂时注释，数据库中不存在这些字段
    # total_score = Column(Float, comment='总分')
    # duration = Column(Integer, comment='测评时长(秒)')
    
    # 关系
    user = relationship('User', back_populates='assessments')
    scale = relationship('Scale', back_populates='assessments')
    publication = relationship('MemberScalePublication', back_populates='assessments')
    answers = relationship('AssessmentAnswer', back_populates='assessment', cascade='all, delete-orphan')
    scores = relationship('AssessmentScore', back_populates='assessment', cascade='all, delete-orphan')
    
    def __repr__(self):
        return f'<Assessment {self.id}: User {self.user_id} - Scale {self.scale_id}>'
    
    @property
    def status_value(self):
        """获取状态的字符串值，用于JSON序列化"""
        return self.status.value if isinstance(self.status, AssessmentStatus) else self.status
    
    @property
    def is_completed(self):
        """是否已完成"""
        return self.status == AssessmentStatus.COMPLETED
    
    @property
    def is_in_progress(self):
        """是否进行中"""
        return self.status == AssessmentStatus.IN_PROGRESS
    
    def to_dict(self, exclude=None, include_relationships=False):
        """转换为字典格式，处理枚举类型序列化"""
        exclude = exclude or []
        result = super().to_dict(exclude=exclude, include_relationships=include_relationships)
        
        # 处理枚举类型的序列化
        if 'status' in result and hasattr(self.status, 'value'):
            result['status'] = self.status.value
        
        return result
    
    def calculate_progress(self):
        """计算完成进度"""
        if self.total_questions and self.total_questions > 0:
            # 统计已回答的题目数量（有selected_options或answer_text的记录）
            answered_count = len([
                a for a in self.answers 
                if a.selected_options is not None or (a.answer_text and a.answer_text.strip())
            ])
            self.progress_percentage = (answered_count / self.total_questions) * 100
        return self.progress_percentage
    
    def update_time_spent(self):
        """更新已用时间"""
        if self.started_at:
            now = datetime.utcnow()
            if self.completed_at:
                self.time_spent = int((self.completed_at - self.started_at).total_seconds())
            else:
                self.time_spent = int((now - self.started_at).total_seconds())
        return self.time_spent


class AssessmentAnswer(BaseModel):
    """测评答案"""
    __tablename__ = 'assessment_answers'
    
    # 基本信息
    assessment_id = Column(Integer, ForeignKey('assessments.id'), nullable=False, comment='测评ID')
    question_id = Column(Integer, ForeignKey('scale_questions.id'), nullable=False, comment='题目ID')
    question_number = Column(Integer, nullable=False, comment='题目序号')
    
    # 答案内容
    answer_value = Column(Text, comment='答案值')
    answer_text = Column(Text, comment='答案文本')
    # selected_options = Column(JSON, comment='选中的选项(JSON格式)')  # 数据库表中不存在此字段，临时注释
    
    # 答题信息
    answered_at = Column(DateTime, default=datetime.utcnow, comment='答题时间')
    time_spent = Column(Integer, default=0, comment='答题用时(秒)')
    
    # 答题状态
    is_skipped = Column(Boolean, default=False, comment='是否跳过')
    is_reviewed = Column(Boolean, default=False, comment='是否已回顾')
    review_count = Column(Integer, default=0, comment='回顾次数')
    
    # 计分信息
    raw_score = Column(Float, comment='原始分数')
    weighted_score = Column(Float, comment='加权分数')
    
    # 关系
    assessment = relationship('Assessment', back_populates='answers')
    question = relationship('ScaleQuestion')
    
    # 临时属性，用于兼容代码中对selected_options的访问
    @property
    def selected_options(self):
        """从answer_value解析选中的选项"""
        if self.answer_value:
            try:
                import json
                return json.loads(self.answer_value)
            except:
                return self.answer_value
        return None
    
    @selected_options.setter
    def selected_options(self, value):
        """将选中的选项保存到answer_value"""
        if value is not None:
            import json
            if isinstance(value, (list, dict)):
                self.answer_value = json.dumps(value)
            else:
                self.answer_value = str(value)
        else:
            self.answer_value = None
    
    def __repr__(self):
        return f'<AssessmentAnswer {self.assessment_id}-{self.question_number}>'
    
    def calculate_score(self):
        """计算答案分数"""
        if not self.selected_options or not self.question:
            return 0.0
        
        total_score = 0.0
        try:
            if isinstance(self.selected_options, list):
                # 多选题
                for option_id in self.selected_options:
                    option = next((opt for opt in self.question.options if opt.id == option_id), None)
                    if option and option.option_value is not None:
                        total_score += option.option_value
            else:
                # 单选题
                option_id = self.selected_options
                option = next((opt for opt in self.question.options if opt.id == option_id), None)
                if option and option.option_value is not None:
                    total_score = option.option_value
        except Exception:
            total_score = 0.0
        
        self.raw_score = total_score
        return total_score


class AssessmentScore(BaseModel):
    """测评得分"""
    __tablename__ = 'assessment_scores'
    
    # 基本信息
    assessment_id = Column(Integer, ForeignKey('assessments.id'), nullable=False, comment='测评ID')
    scoring_rule_id = Column(Integer, ForeignKey('scale_scoring_rules.id'), comment='计分规则ID')
    
    # 得分信息
    dimension_name = Column(String(100), comment='维度名称')
    raw_score = Column(Float, nullable=False, comment='原始分数')
    standard_score = Column(Float, comment='标准分数')
    percentile = Column(Float, comment='百分位数')
    
    # 分数解释
    score_level = Column(String(50), comment='分数等级')
    interpretation = Column(Text, comment='分数解释')
    suggestions = Column(Text, comment='建议')
    
    # 统计信息
    min_possible_score = Column(Float, comment='最低可能分数')
    max_possible_score = Column(Float, comment='最高可能分数')
    mean_score = Column(Float, comment='平均分数')
    std_deviation = Column(Float, comment='标准差')
    
    # 计算时间
    calculated_at = Column(DateTime, default=datetime.utcnow, comment='计算时间')
    
    # 关系
    assessment = relationship('Assessment', back_populates='scores')
    scoring_rule = relationship('ScaleScoringRule')
    
    def __repr__(self):
        return f'<AssessmentScore {self.assessment_id}-{self.dimension_name}: {self.raw_score}>'
    
    @property
    def score_percentage(self):
        """得分百分比"""
        if self.min_possible_score is not None and self.max_possible_score is not None:
            score_range = self.max_possible_score - self.min_possible_score
            if score_range > 0:
                return ((self.raw_score - self.min_possible_score) / score_range) * 100
        return 0.0
    
    def get_score_level(self):
        """获取分数等级"""
        percentage = self.score_percentage
        if percentage >= 90:
            return '优秀'
        elif percentage >= 80:
            return '良好'
        elif percentage >= 70:
            return '中等'
        elif percentage >= 60:
            return '及格'
        else:
            return '不及格'